package com.heatup.apt.management.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.heatup.apt.common.constants.UserConstants;
import com.heatup.apt.common.dao.SmsLogMapper;
import com.heatup.apt.common.util.CheckCodeUtil;
import com.heatup.apt.common.util.JsonUtils;
import com.heatup.apt.common.util.SmsUtil;
import com.heatup.apt.management.service.company.CompanyInfoService;
import com.heatup.apt.management.service.company.CompanyRechargeService;
import com.heatup.apt.management.service.company.CompanyStaffService;
import com.heatup.apt.management.service.coupon.CouponService;
import com.heatup.apt.management.service.store.StoreService;
import com.heatup.apt.management.util.ManageConfigPropertiesUtil;
import com.heatup.apt.model.SmsLog;
import com.heatup.apt.model.company.CompanyInfo;
import com.heatup.apt.model.company.CompanyRecharge;
import com.heatup.apt.model.company.CompanyStaff;
import com.heatup.apt.model.order.OrderCompanyDetail;
import com.heatup.apt.model.order.OrderCompanyDetailInfo;
import com.heatup.apt.model.order.OrderCompanyInfo;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 企业 控制层
 */
@Controller
@RequestMapping(value = "/system/company")
public class CompanyController extends BaseController {

    public static final Logger log = LoggerFactory.getLogger(CompanyController.class);

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private CompanyStaffService companyStaffService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private CompanyRechargeService companyRechargeService;

    @Autowired
    private SmsLogMapper smsLogMapper;

    @Autowired
    private StoreService storeService;

    /**
     * 企业储值卡
     *
     * @return 企业列表页面
     */
    @RequestMapping(value = "/list")
    public ModelAndView listUI() {
        return new ModelAndView("company/company_list");
    }

    /**
     * 企业储值卡添加/编辑 step1
     *
     * @param id 企业ID
     * @return 企业列表添加页面 step1
     */
    @RequestMapping(value = "/add_step1")
    public ModelAndView companyAddStep1(Long id) {
        ModelAndView modelAndView = new ModelAndView("company/company_add_step1");
        modelAndView.addObject("checkList", couponService.queryAllCheckList(2));
        modelAndView.addObject("storeList", storeService.queryAllOnlineStore());
        if (id != null) {
            CompanyInfo companyInfo = companyInfoService.selectById(id);
            modelAndView.addObject("company", companyInfo);
            modelAndView.addObject("companyAmount", companyInfoService.selectCompanyAmountById(id));
            modelAndView.addObject("companyJson", JSON.toJSONString(companyInfo));
            String user_company_binding_url = ManageConfigPropertiesUtil.getString("company_binding_url").trim();
            modelAndView.addObject("companyBindingUrl", user_company_binding_url.replace("${companyId}", String.valueOf(id)));
        }
        return modelAndView;
    }

    /**
     * 企业储值卡添加 step2
     *
     * @param id 企业ID
     * @return 企业列表添加页面 step2
     */
    @RequestMapping(value = "/add_step2")
    public ModelAndView companyAddStep2(@RequestParam Long id) {
        ModelAndView modelAndView = new ModelAndView("company/company_add_step2");
        modelAndView.addObject("id", id);
        modelAndView.addObject("checkList", couponService.queryAllCheckList(1));//共用校验人列表
        return modelAndView;
    }

    /**
     * 企业储值卡充值
     *
     * @return 企业储值卡充值页面
     */
    @RequestMapping(value = "/recharge")
    public ModelAndView recharge(@RequestParam Long id) {
        ModelAndView modelAndView = new ModelAndView("company/company_recharge");
        modelAndView.addObject("company", companyInfoService.selectById(id));
        modelAndView.addObject("checkList", couponService.queryAllCheckList(2));//充值验证人
        return modelAndView;
    }

    /**
     * 企业员工添加/编辑
     *
     * @return 企业员工添加/编辑页面
     */
    @RequestMapping(value = "/empl_add")
    public ModelAndView emplAdd(@RequestParam Long companyId, Long id) {
        ModelAndView modelAndView = new ModelAndView("company/company_empl_add");
        if (id != null) {
            modelAndView.addObject("companyStaff", companyStaffService.selectById(id));
        }
        modelAndView.addObject("company", companyInfoService.selectById(companyId));
        return modelAndView;
    }

    /**
     * 企业员工列表 
     *
     * @return 企业员工列表页面
     */
    @RequestMapping(value = "/empl_list")
    public ModelAndView emplList(@RequestParam Long companyId) {
        ModelAndView modelAndView = new ModelAndView("company/company_empl_list");
        modelAndView.addObject("companyId", companyId);
        modelAndView.addObject("company", companyInfoService.selectById(companyId));
        return modelAndView;
    }

    /**
     * 企业订单列表
     *
     * @return 企业员订单列表页面
     */
    @RequestMapping(value = "/order_list")
    public ModelAndView orderList(Long companyId) {
        ModelAndView modelAndView = new ModelAndView("company/company_order_list");
        modelAndView.addObject("companyId", companyId);
        return modelAndView;
    }

    /**
     * 企业储值卡 企业分页
     *
     * @param pageIndex 页码 1开始
     * @param pageSize  页面大小
     * @return 列表数据
     */
    @RequestMapping(value = "/companyList")
    @ResponseBody
    public String list(@RequestParam Integer pageIndex, @RequestParam Integer pageSize, CompanyInfo companyInfoQuery) {

        Page<CompanyInfo> companyInfoPage = new Page<>(pageIndex, pageSize);
        companyInfoPage = companyInfoService.selectCompanyList(companyInfoPage, companyInfoQuery);
        JSONObject jsonResult = new JSONObject();
        jsonResult.put("list", companyInfoPage.getRecords());
        jsonResult.put("count", companyInfoPage.getTotal());
        return JsonUtils.toJsonStrWithDateFormat(jsonResult);
    }

    /**
     * 企业储值卡 员工分页
     *
     * @param pageIndex 页码 1开始
     * @param pageSize  页面大小
     * @return 列表数据
     */
    @RequestMapping(value = "/emplList")
    @ResponseBody
    public String emplList(@RequestParam Integer pageIndex, @RequestParam Integer pageSize, CompanyStaff companyStaffQuery) {

        Map<String, Object> resultMap = companyStaffService.list(pageIndex, pageSize, companyStaffQuery);
        return JsonUtils.toJsonStrWithDateFormat(resultMap);
    }

    /**
     * 企业保存step1
     *
     * @param companyInfo 企业
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/save_company_step1")
    @ResponseBody
    public String saveCompanyStep1(CompanyInfo companyInfo) {
        JSONObject resultJson = new JSONObject();
        resultJson.put("success", false);
        if (companyInfo != null) {
            boolean check = false;
            if (companyInfo.getStatus() == null) {
                check = companyInfoService.checkByName(companyInfo);
            }
            if (check) {
                resultJson.put("msg", "存在名称相同的公司,请修改后再试");
                return resultJson.toJSONString();
            } else {
                if (companyInfo.getStatus() != null) {
                    resultJson.put("go", "list");
                }
                resultJson.put("success", companyInfoService.saveCompany(companyInfo, getUserInfo().getId()));
                resultJson.put("id", companyInfo.getId());
            }
        }
        return JsonUtils.toJsonStrWithDateFormat(resultJson);
    }

    /**
     * 企业员工保存
     *
     * @param companyStaff 企业员工
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/saveCompanyStaff")
    @ResponseBody
    public String saveCompanyStaff(CompanyStaff companyStaff) {

        JSONObject resultJson = new JSONObject();
        resultJson.put("success", false);
        if (companyStaff != null && companyStaff.getId() == null) {
            boolean check = companyStaffService.checkByMobile(companyStaff);
            if (check) {
                resultJson.put("msg", "存在手机号码相同的员工,请修改后再试");
                return resultJson.toJSONString();
            }
        }
        if (companyStaff != null && companyStaff.getStatus() != null) {
            resultJson.put("go", "list");
        }
        boolean result = companyStaffService.saveCompanyStaff(companyStaff, getUserInfo().getId());
        resultJson.put("success", result);
        if (result && companyStaff != null) {
            resultJson.put("id", companyStaff.getId());
        }

        return JsonUtils.toJsonStrWithDateFormat(resultJson);
    }

    /**
     * 发送验证码
     *
     * @param mobile 手机号
     * @return success成功
     */
    @RequestMapping(value = "/send")
    @ResponseBody
    private String send(@RequestParam String mobile) {
        Integer userId = getUserInfo().getId();

        //未登陆
        if (userId == null) {
            return "用户未登陆";
        }

        try {
            //检查发送间隔
            Object lastSend = this.getSession(SESSION_KEY_CHECK_CODE_LAST_SEND);
            if (lastSend != null) {
                long lastSendTime = (long) lastSend;
                long currentTime = System.currentTimeMillis();
                long seconds = (currentTime - lastSendTime) / 1000;
                if (seconds < UserConstants.SEND_CHECK_CODE_INTERVAL) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("nextSendSecond", seconds);
                    return "验证码发送太频繁";
                }
            }

            //检查后台管理员发送限额
            int todayMyCount = smsLogMapper.queryManagementSmsCountByMobileAndUserId(mobile, userId);
            if (todayMyCount > UserConstants.CHECK_CODE_MAX_SEND_COUNT) {
                return "已超过今天短信限额";
            }

            Map<String, Object> map = new HashMap<>();
            int checkCode = CheckCodeUtil.getCheckCode();
            boolean sendResult = SmsUtil.sendCheckCode(mobile, checkCode + "");

            //发送记录
            SmsLog smsLog = new SmsLog();
            smsLog.setMobile(mobile);
            smsLog.setCheckCode(checkCode + "");
            smsLog.setUserId(userId);
            smsLog.setSendTime(new Date());
            smsLog.setSendResult(sendResult ? 1 : 2);
            smsLog.setSendType(1);
            smsLogMapper.insertSelective(smsLog);

            this.setSession(SESSION_KEY_MOBILE, mobile);
            this.setSession(SESSION_KEY_CHECK_CODE, checkCode);
            this.setSession(SESSION_KEY_CHECK_CODE_LAST_SEND, System.currentTimeMillis());
            map.put("nextSendSecond", UserConstants.SEND_CHECK_CODE_INTERVAL);
            return "success";

        } catch (Exception e) {
            return "系统错误" + e.getMessage();
        }
    }

    /**
     * 校验验证码
     *
     * @param checkCode 验证码
     */
    @RequestMapping(value = "/check_code")
    @ResponseBody
    private String checkCheckCode(@RequestParam String checkCode) {

        Integer userId = getUserInfo().getId();

        //未登陆
        if (userId == null) {
            return "未登陆";
        }

        try {
            //有效期验证
            Object syscode = this.getSession(SESSION_KEY_CHECK_CODE);
            Object lastSend = this.getSession(SESSION_KEY_CHECK_CODE_LAST_SEND);
            if (syscode == null || lastSend == null) {

                return "无验证码";
            }

            long lastSendTime = (long) lastSend;
            long currentTime = System.currentTimeMillis();
            long seconds = (currentTime - lastSendTime) / 1000;
            if (seconds > UserConstants.CHECK_CODE_TIMEOUT) {
                return "验证码已失效,请重新发送";
            }

            //验证码验证
            if (syscode.toString().length() > 0 && syscode.toString().equals(checkCode)) {
                //验证成功
                return "success";
            } else {
                return "验证码错误";
            }
        } catch (Exception e) {
            return "系统错误" + e.getMessage();
        }
    }

    /**
     * 企业上线
     *
     * @param id        企业ID
     * @param checkName 验证人
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/onlineCompany")
    @ResponseBody
    public String onlineCompany(Long id, String checkName) {
        //验证成功 上线企业
        CompanyInfo companyInfo = new CompanyInfo();
        companyInfo.setId(id);
        companyInfo.setCheckedBy(checkName);
        companyInfo.setStatus(1);
        boolean result = companyInfoService.updateSelectiveById(companyInfo);
        if (result) {
            return "success";
        } else {
            return "fail";
        }

    }

    /**
     * 冻结企业
     *
     * @param companyInfo 企业
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/lockCompany")
    @ResponseBody
    public String lockCompany(CompanyInfo companyInfo) {

        if (companyInfo.getId() == null)
            return "fail";
        companyInfo.setStatus(2);
        boolean updated = companyInfoService.updateSelectiveById(companyInfo);
        if (updated) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 解冻企业
     *
     * @param companyInfo 企业
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/unlockCompany")
    @ResponseBody
    public String unlockCompany(CompanyInfo companyInfo) {

        if (companyInfo.getId() == null)
            return "fail";
        companyInfo.setStatus(1);
        boolean updated = companyInfoService.updateSelectiveById(companyInfo);
        if (updated) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 冻结员工
     *
     * @param companyStaff 企业员工
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/lockEmpl")
    @ResponseBody
    public String lockEmpl(CompanyStaff companyStaff) {

        if (companyStaff.getId() == null)
            return "fail";
        companyStaff.setStatus(1);
        boolean updated = companyStaffService.updateSelectiveById(companyStaff);
        if (updated) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 解冻员工
     *
     * @param companyStaff 企业员工
     * @return success -->true成功/false失败
     */
    @RequestMapping(value = "/unlockEmpl")
    @ResponseBody
    public String unlockEmpl
    (CompanyStaff companyStaff) {

        if (companyStaff.getId() == null)
            return "fail";
        companyStaff.setStatus(0);
        boolean updated = companyStaffService.updateSelectiveById(companyStaff);
        if (updated) {
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 离职员工
     *
     * @param companyStaff 企业员工
     * @return success 成功/false失败
     */
    @RequestMapping(value = "/dimissionEmpl")
    @ResponseBody
    public String dimissionEmpl(CompanyStaff companyStaff) {


        if (companyStaff.getId() == null)
            return "fail";
        companyStaff = companyStaffService.selectById(companyStaff.getId());
        if (companyStaff != null) {
            companyStaff.setStatus(2);
            companyStaff.setUserId(null);
            companyStaff.setMobile("#"+ companyStaff.getMobile());
        }
        boolean updated = companyStaffService.updateSelectiveById(companyStaff);
        if (updated) {
            return "success";
        } else {
            return "fail";
        }
    }


    /**
     * 更新企业储值卡余额 及保存企业储值卡充值记录
     *
     * @param companyRecharge 企业充值
     * @return success成功/false失败
     */
    @RequestMapping(value = "/save_company_recharge")
    @ResponseBody
    public String saveCompanyRecharge(CompanyRecharge companyRecharge) {

        boolean result = companyRechargeService.saveCompanyRecharge(companyRecharge, getUserInfo().getId());
        if (result) {
            return "success";
        } else {
            return "fail";
        }
    }


    /**
     * 企业储值卡历史充值流水 分页
     *
     * @param year      年份 2017
     * @param month     月份 1-12
     * @param companyId 企业ID
     * @param pageIndex 页码
     * @param pageSize  页面大小
     * @return 分页数据
     */
    @RequestMapping(value = "/companyRecharge")
    @ResponseBody
    public String companyRechargePage(Integer year, Integer month,
                                      @RequestParam Long companyId,
                                      @RequestParam Integer pageIndex,
                                      @RequestParam Integer pageSize) {

        Page<CompanyRecharge> companyRechargePage = new Page<>(pageIndex, pageSize);
        companyRechargePage = companyRechargeService.selectRechargePage(companyRechargePage, year, month, companyId);
        JSONObject resultJson = new JSONObject();
        resultJson.put("list", companyRechargePage.getRecords());
        resultJson.put("count", companyRechargePage.getTotal());
        return JsonUtils.toJsonStrWithDateFormat(resultJson);
    }


    /**
     * 企业充值详情
     *
     * @param id 企业充值ID
     * @return 企业充值详情
     */
    @RequestMapping(value = "/companyRechargeDetail")
    public ModelAndView companyTransferDocEvidence(@RequestParam Long id) {

        ModelAndView modelAndView = new ModelAndView("company/company_recharge_detail");
        modelAndView.addObject("recharge", companyRechargeService.selectById(id));
        return modelAndView;
    }


    /**
     * 企业消储值卡消费流水
     *
     * @param pageIndex        页码
     * @param pageSize         页面大小
     * @param orderCompanyInfo 企业消费流水查询
     * @return 企业消费流水
     */
    @RequestMapping(value = "/companyOrderHistory")
    @ResponseBody
    public String companyOrderHistory(@RequestParam Integer pageIndex,
                                      @RequestParam Integer pageSize,
                                      OrderCompanyInfo orderCompanyInfo) {

        Map<String, Object> resultMap = companyRechargeService.queryCompanyCostList(pageIndex, pageSize, orderCompanyInfo);
        return JsonUtils.toJsonStrWithDateFormat(resultMap);
    }


    /**
     * 企业储值卡订单流水
     *
     * @param pageIndex          页码
     * @param pageSize           页面大小
     * @param orderCompanyDetail 查询类
     * @return 分页数据
     */
    @RequestMapping(value = "/companyOrderList")
    @ResponseBody
    public String companyOrderPage(@RequestParam Integer pageIndex,
                                   @RequestParam Integer pageSize,
                                   OrderCompanyDetail orderCompanyDetail) {
        Page<OrderCompanyDetail> orderCompanyDetailPage = new Page<>(pageIndex, pageSize);
        orderCompanyDetailPage = companyRechargeService.queryOrderPage(orderCompanyDetailPage, orderCompanyDetail);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("list", orderCompanyDetailPage.getRecords());
        resultMap.put("count", orderCompanyDetailPage.getTotal());
        return JsonUtils.toJsonStrWithDateFormat(resultMap);
    }

    /**
     * 企业储值卡订单 下载当月详情
     *
     * @param orderCompanyDetailInfo 参数
     * @return
     */
    @RequestMapping(value = "/downloadOrderDetail")
    @ResponseBody
    public void downloadOrderDetail(OrderCompanyDetailInfo orderCompanyDetailInfo, HttpServletResponse response) {

        String fileName = companyInfoService.queryOrderDetailList(orderCompanyDetailInfo);

        String baseDir = System.getProperty("user.home") + File.separator + "temp";
        response.setContentType("multipart/form-data");
        try {
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("下载企业储值卡订单年月详情时出错" + e.toString());
        }
        File file = new File(baseDir + File.separator + fileName);
        FileInputStream fis = null;
        OutputStream ops = null;
        try {
            fis = new FileInputStream(file);
            HSSFWorkbook wb = new HSSFWorkbook(fis);
            ops = response.getOutputStream();
            wb.write(ops);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
                ops.close();
            } catch (Exception e) {
                e.printStackTrace();
                log.error("下载企业储值卡订单年月详情时出错" + e.toString());
            }
        }
    }

}